package com.zhuoyue.web.controller;

import com.alibaba.fastjson.JSONObject;
import com.zhuoyue.biz.core.api.domain.GatewayDO;
import com.zhuoyue.biz.core.api.dto.rep.LocalSceneRepDTO;
import com.zhuoyue.biz.core.api.dto.req.LocalSceneAddDTO;
import com.zhuoyue.biz.core.api.dto.req.LocalSceneModifyDTO;
import com.zhuoyue.biz.core.api.service.GatewayService;
import com.zhuoyue.biz.core.api.service.impl.GatewayTimingSceneService;
import com.zhuoyue.biz.core.api.service.impl.GeofencingService;
import com.zhuoyue.biz.core.api.service.impl.LocalSceneService;
import com.zhuoyue.common.aop.auth.CheckLogin;
import com.zhuoyue.common.aop.auth.User;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;

import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import com.zhuoyue.biz.core.api.domain.LocalSceneDO;
import com.zhuoyue.biz.core.api.service.GatewayRedisService;
import com.zhuoyue.biz.core.command.constant.SceneCmdDeal;
import com.zhuoyue.common.dto.ControllerResult;
import com.zhuoyue.common.utils.CmdUtils;

import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotBlank;


/**
 * @author wjming
 * @ClassName: AppLocalSceneController
 * @Description:
 * @Date 2021/4/16 14:39
 */
@RestController
@Scope("prototype")
@RequestMapping("/api/localScene")
@Validated
@Slf4j
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class AppLocalSceneController {
    private final LocalSceneService localSceneService;
    private final GatewayRedisService gatewayRedisService;
    private final GatewayService gatewayService;
    private final GeofencingService geofencingService;
    private final GatewayTimingSceneService gatewayTimingSceneService;

    /**
     * 查询家庭中的本地场景列表
     *
     * @param homeId
     * @return
     */

    @GetMapping("/list")
    @CheckLogin
    public ControllerResult getLocalSceneList(@RequestParam @NotBlank(message = "家庭ID不能为空") String homeId) {
        return ControllerResult.toReturnDataSuccess("本地场景获取成功", localSceneService.getLocalSceneListByHomeId(homeId));
    }

    /**
     * 新增本地场景
     *
     * @param localSceneAddDTO
     * @return
     */
    @PostMapping("/add")
    @CheckLogin
    public ControllerResult addLocalScene(@Validated @RequestBody LocalSceneAddDTO localSceneAddDTO, HttpServletRequest request) {
        User user = (User) request.getAttribute("user");
        log.info("request -> user:[{}_{}] [addLocalScene] -> [localSceneAddDTO:{}]",
                user.getAccount(), user.getOrgCode(), JSONObject.toJSONString(localSceneAddDTO));
        //根据homeId查询网关信息
        GatewayDO gatewayDO = gatewayService.getByHomeId(localSceneAddDTO.getHomeId());
        if (gatewayDO == null) {
            return ControllerResult.toParamFail("请先添加网关");
        }
        LocalSceneDO localSceneDO = new LocalSceneDO();
        BeanUtils.copyProperties(localSceneAddDTO, localSceneDO);
        localSceneDO.setGatewayMac(gatewayDO.getZigbeeMac());
        LocalSceneDO result = localSceneService.addLocalScene(localSceneDO);
        LocalSceneRepDTO localSceneRepDTO = new LocalSceneRepDTO();
        BeanUtils.copyProperties(result, localSceneRepDTO);
        localSceneRepDTO.setCreateTime(result.getCreateTime());
        log.info("result -> [addLocalScene] -> [localSceneRepDTO:{}]",
                user.getAccount(), user.getOrgCode(), localSceneRepDTO);
        return ControllerResult.toReturnDataSuccess("场景添加成功", localSceneRepDTO);
    }


    /**
     * 修改本地场景信息
     *
     * @return
     */
    @PutMapping("/modify")
    @CheckLogin
    public ControllerResult updateLocalScene(@Validated @RequestBody LocalSceneModifyDTO localSceneModifyDTO, HttpServletRequest request) {
        User user = (User) request.getAttribute("user");
        log.info("request -> user:[{}_{}] [updateLocalScene] -> [localSceneModifyDTO:{}]",
                user.getAccount(), user.getOrgCode(), JSONObject.toJSONString(localSceneModifyDTO));

        LocalSceneDO localSceneDO = new LocalSceneDO();
        BeanUtils.copyProperties(localSceneModifyDTO, localSceneDO);
        //先删除之前的场景关系信息
        LocalSceneDO result = localSceneService.updateLocalSceneById(localSceneDO);
        LocalSceneRepDTO localSceneRepDTO = new LocalSceneRepDTO();
        BeanUtils.copyProperties(result, localSceneRepDTO);
        localSceneRepDTO.setCreateTime(result.getCreateTime());
        log.info("result -> [updateLocalScene] -> [localSceneRepDTO:{}]",
                user.getAccount(), user.getOrgCode(), localSceneRepDTO);
        return ControllerResult.toReturnDataSuccess("场景信息修改成功", localSceneRepDTO);
    }


    /**
     * 删除本地场景
     *
     * @param id
     * @return
     */
    @DeleteMapping("/delete")
    @CheckLogin
    public ControllerResult deleteLocalScene(@RequestParam @NotBlank(message = "本地场景ID不能为空") String id) {
        LocalSceneDO byId = localSceneService.getById(id);
        if (byId == null) {
            return ControllerResult.toNoDataFail("该场景不存在");
        }
        if (byId.getGatewayMac() != null) {
            String sceneClearCmd = getSceneClearCmd(byId
                    .getGatewayMac(), byId.getCode() + "");
            // 发送指令
            gatewayRedisService.writeDataToGateway(byId.getGatewayMac(), sceneClearCmd);
            log.info("request -> [deleteLocalScene] -> [deleteScene:{}]", sceneClearCmd);
        }
        localSceneService.removeById(id);
        localSceneService.removeSceneAndParam(id);
        return ControllerResult.toReturnMessageSuccess("删除成功");
    }


    private String getSceneClearCmd(String gatewayMac, String code) {

        String cmd3To8 = SceneCmdDeal.SceneClear.CMD_3
                + SceneCmdDeal.SceneClear.CMD_4 + gatewayMac
                + SceneCmdDeal.SceneClear.CMD_6
                + SceneCmdDeal.SceneClear.CMD_7
                + CmdUtils.intToHexTwo(Integer.parseInt(code));

        String cmd2 = CmdUtils.getDateLength(cmd3To8);

        String cmd9 = CmdUtils.getCmdBodySum(cmd3To8);

        String fullCmd = SceneCmdDeal.SceneClear.CMD_1 + cmd2 + cmd3To8
                + cmd9 + SceneCmdDeal.SceneClear.CMD_10;

        return fullCmd;
    }

}
